package com.sh.rbac.core.mybatis.config;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.DataPermissionInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.sh.rbac.core.mybatis.context.DataPermissionContext;
import com.sh.rbac.core.mybatis.properties.DataPermissionProperties;
import lombok.AllArgsConstructor;
import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;

/**
 * MybatisPlus配置类
 *
 * @author lucky
 */

@MapperScan("com.sh.rbac.mapper") // 扫描 mapper
@AllArgsConstructor
@EnableConfigurationProperties(DataPermissionProperties.class)
@EnableTransactionManagement //事务处理
@Configuration
public class MybatisPlusConfig {

    private final DataPermissionProperties dataPermissionProperties;

    /**
     * 分页插件
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();

        // 数据权限拦截器
        if (Boolean.TRUE.equals(dataPermissionProperties.getEnabled())) {
            interceptor.addInnerInterceptor(new DataPermissionInterceptor((where, mappedStatementId) -> {
                Expression currentExpression = DataPermissionContext.getCurrentExpression();
                
                if (currentExpression == null) {
                    return where;
                }

                if (where != null) {
                    try {
                        return CCJSqlParserUtil.parseCondExpression(where + " AND (" + currentExpression + ")");
                    } catch (JSQLParserException e) {
                        throw new RuntimeException(e);
                    }
                } else {
                    return currentExpression;
                }
            }));
        }

        // 分页拦截器
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));

        // 乐观锁拦截器
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());

        // 阻止恶意的全表更新删除
        interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());

        return interceptor;
    }

}
